package com.shelpe.services.algorithm.development;

import java.math.BigDecimal;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.shelpe.services.algorithm.client.RankClient;
import com.shelpe.services.algorithm.configuration.MobileQscoreProperties;
import com.shelpe.services.algorithm.constant.MobileRank;
import com.shelpe.services.algorithm.entity.jpa.DevelopmentPlan;
import com.shelpe.services.algorithm.entity.jpa.DevelopmentPlan.PremiumType;
import com.shelpe.services.algorithm.entity.mongo.KeywordDevelopmentLog;
import com.shelpe.services.algorithm.repository.jpa.DevelopmentKeywordRepository;
import com.shelpe.services.algorithm.sustain.SustainRule;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class KeywordDevelopmentSustainRule implements SustainRule<KeywordDevelopmentSustainer> {

	@Autowired
	private DevelopmentKeywordRepository developmentKeywordRepository;
	@Autowired
	private MobileQscoreProperties mobileQscoreProperties;
	
	@Value("${algorithm.allow.ip:221.176.172.86}")
	private String allowedIP;
	
	@Override
	public boolean check(KeywordDevelopmentSustainer entity) {
		log.debug("keyword development: {}", entity);
		return entity.getTarget() != null && entity.getKeyword() != null;
	}

	@Override
	public boolean prepare(KeywordDevelopmentSustainer entity) {
		if(entity.getRank() == null){
			log.warn("no rank and set as default one: {}", entity.getTarget());
			RankClient.KeywordRealtimeRankItem rank = new RankClient.KeywordRealtimeRankItem();
			rank.setKeywordID(entity.getKeyword().getKeywordId());
			rank.setState(1);
			rank.setPcRank(-1);
			rank.setMoibleRank(-1);
			entity.setRank(rank);
		}
		
		Date now = new Date();
		entity.setLog(new KeywordDevelopmentLog());
		entity.getLog().setCurrentRank(entity.getRank());
		entity.getLog().setTarget(entity.getTarget());
		entity.getLog().setupID(entity.getKeyword().getKeywordId(), now);
		entity.getLog().setLogTime(now);
		
		entity.getLog().setKeywordID(entity.getKeyword().getKeywordId());
		entity.getLog().setUserID(entity.getPlan().getUserID());
		entity.getLog().setContainerID(entity.getPlan().getContainerID());
		entity.getLog().setPlanID(entity.getPlan().getAutoID());
		
		entity.getLog().setupOriginalKeyword(entity.getKeyword());
		return true;
	}

	@Override
	public SustainRule.SustainStatus sustain(KeywordDevelopmentSustainer entity) {
		if(entity.getPlan().getDevice() == 1){
			entity.getTarget().setLastRank(entity.getRank().getMoibleRank());
		}else{
			entity.getTarget().setLastRank(entity.getRank().getPcRank());
		}
		
		SustainRule.SustainStatus ss = SustainRule.SustainStatus.keep;
		
		BigDecimal premium = entity.getPlan().getPremium();
		if(entity.getTarget().getPremiumType() != null && entity.getTarget().getPremium() != null){
			premium = entity.getTarget().getPremium();
		}
		
		if(premium.floatValue() > 0){
			//排名不够或者最近一次排名未知
			if(entity.getTarget().getTarget() < entity.getTarget().getLastRank() || entity.getTarget().getLastRank() == -1){
				ss = SustainRule.SustainStatus.pricing;
			}
		}
		if(premium.floatValue() < 0){
			if(entity.getTarget().getTarget() >= entity.getTarget().getLastRank()){
				ss = SustainRule.SustainStatus.pricing;
			}
			
			//目标排名是20名以后就不用降价了
			if(ss == SustainRule.SustainStatus.pricing 
					&& entity.getTarget().getLastRank() == MobileRank.after20OfIndex.getValue()){
				ss = SustainRule.SustainStatus.keep; 
			}
		}
		
		return ss;
	}

	@Override
	public boolean maintain(KeywordDevelopmentSustainer entity,
			SustainRule.SustainStatus status) {
		if(status == SustainRule.SustainStatus.pricing){
			PremiumType premiumType = entity.getPlan().getPremiumType();
			BigDecimal premium = entity.getPlan().getPremium();
			if(entity.getTarget().getPremiumType() != null && entity.getTarget().getPremium() != null){
				premiumType = entity.getTarget().getPremiumType();
				premium = entity.getTarget().getPremium();
				if(entity.getTarget().getPremiumType() == PremiumType.precentage){//fix bug: the precentage is integer instead of float
					premium = premium.divide(BigDecimal.valueOf(100));
				}
			}
			
			int mobilePrice = entity.getKeyword().getMaxMobilePrice();
			int price = entity.getKeyword().getMaxPrice();
			log.debug("want to pricing: {}", entity.getKeyword());
			if(premiumType == DevelopmentPlan.PremiumType.precentage){
				mobilePrice = (int) (mobilePrice * (1 + premium.floatValue()));
				price = (int) (price * (1 + premium.floatValue()));
			}else{
				price = price + ((int) (premium.floatValue() * 100));
				mobilePrice = mobilePrice + ((int) (premium.floatValue() * 100));
			}
			
			log.debug("pricing premium: {} {}", price, mobilePrice);
			if(entity.getPlan().getDevice() == 1){
				entity.getKeyword().setMaxMobilePrice(mobilePrice);
				entity.getKeyword().setMaxMobilePrice(Math.min(entity.getKeyword().getMaxMobilePrice(), ((int) (entity.getPlan().getLimitValve().floatValue() * 100))));
				entity.getKeyword().setMaxPrice(this.mobileQscoreProperties.calcPcPrice(mobilePrice));
				entity.getKeyword().setMaxPrice(Math.max(entity.getKeyword().getMaxPrice(), 5));
			}else if(entity.getPlan().getDevice() == 2){
				entity.getKeyword().setMaxPrice(price);
				entity.getKeyword().setMaxPrice(Math.min(entity.getKeyword().getMaxPrice(), ((int) (entity.getPlan().getLimitValve().floatValue() * 100))));
				entity.getKeyword().setMaxMobilePrice(entity.getKeyword().getMaxPrice() * 150 / 100);//TODO: base on mobile discount?
			}else{
				entity.getKeyword().setMaxMobilePrice(mobilePrice);
				entity.getKeyword().setMaxPrice(price);
			}
			
			if(entity.getPlan().getLimitValve().floatValue() > 0){
				entity.getKeyword().setMaxPrice(Math.min(entity.getKeyword().getMaxPrice(), ((int) (entity.getPlan().getLimitValve().floatValue() * 100))));
				entity.getKeyword().setMaxMobilePrice(Math.min(entity.getKeyword().getMaxMobilePrice(), ((int) (entity.getPlan().getLimitValve().floatValue() * 100))));
			
			}
			
			entity.getLog().setAction("pricing");
			entity.getLog().setupNewKeyword(entity.getKeyword());
		}
		
		if(status == SustainRule.SustainStatus.match){
			int original = entity.getKeyword().getMatchscope();
			int expected = Math.abs(entity.getTarget().getTargetType().getValue());
			log.debug("change to match scope: {} - {}", original, expected);
			entity.getKeyword().setMatchscope(expected);
			
			entity.getLog().setAction("matching");
			entity.getLog().setupNewKeyword(entity.getKeyword());
		}
		
		return true;
	}

	@Override
	public boolean mark(KeywordDevelopmentSustainer entity) {
		entity.getTarget().setModifiedTime(new Date());
		this.developmentKeywordRepository.save(entity.getTarget());
		return true;
	}

}
